<template>
    <div :class="{ wrapper: uploadeFileList.length >= limit }">
        <!-- 文件上传组件：这里以element-ui为例，其他相同 -->
        <!-- 图片类可预览文件上传 -->
        <el-upload v-if="isImage" action="fakePath" :before-upload="filterFile" :http-request="uploadFile"
            list-type="picture-card" :multiple="mutiple" :limit="limit" :on-remove="handleRemove"
            :on-exceed="handleExceed" :accept="accept" :file-list="uploadeFileList" :disabled="disabled">
            <i class="el-icon-plus"></i>
            <div slot="file" slot-scope="{file}">
                <img class="el-upload-list__item-thumbnail" :src="file.url" alt="">
                <span class="el-upload-list__item-actions">
                    <span v-if="!disabled" class="el-upload-list__item-delete" @click="swapLeft(file)">
                        <i class="el-icon-back"></i>
                    </span>
                    <span v-if="!disabled" class="el-upload-list__item-delete" @click="handleRemove(file)">
                        <i class="el-icon-delete"></i>
                    </span>
                    <span v-if="!disabled" class="el-upload-list__item-delete" @click="swapRight(file)">
                        <i class="el-icon-right"></i>
                    </span>
                </span>
            </div>
            <div slot="tip" class="tips">{{ tips }}</div>
        </el-upload>

        <!-- zip等不可预览文件上传 -->
        <el-upload v-else action="fakePath" :multiple="mutiple" :limit="limit" :on-exceed="handleExceed"
            :before-upload="filterFile" :http-request="uploadFile" :accept="accept" :file-list="uploadeFileList"
            :on-remove="handleRemove" :disabled="disabled">
            <el-button size="small" type="primary" >点击上传</el-button>
            <div slot="tip" class="tips">{{ tips }}</div>
        </el-upload>

        <div style="padding: 20px 10px;" v-show="this.uploadPercentList.length">
            <el-progress style="margin-top: 10px;" v-for="percentEle in uploadPercentList" :key="percentEle.id"
                :percentage="percentEle.percent"></el-progress>
        </div>
    </div>
</template>

<script>
import { uploadSingleFile, getFileNameWithUrl, checkFileMimalType, formatFileSize, } from "../upload";
import { mergeObject, deepCopy, getRandomDateString as getRandomTimeStr } from "../utils";

export default {
    props: {
        isImage: { // 是否为图片上传（图片上传存在预览）
            type: Boolean,
            default: true,
        },
        disabled: Boolean, // 是否disable禁止操作
        accept: { // 接受的文件类型
            type: String,
            default: 'image/*',
        },
        mutiple: { // 是否上传多个文件
            type: Boolean,
            default: false,
        },
        limit: { // 上传多个文件的最大数量(0表示不限制)
            type: Number,
            default: 0,
        },
        folder: { // 上传的文件路径(必填)
            type: String,
            required: true,
        },
        tips: { // 提示文本
            type: String,
            default: ''
        },
        orginFileList: { // 原本已上传的文件，用于编辑
            type: Array | String,
            default: () => []
        },
        maxSizeMB: {
            type: Number,
            default: 10,
        },
    },
    watch: {
        orginFileList: {
            handler(newArr, oldArr) {
                const notExist = (url) => this.uploadeFileList.findIndex(el => el.url == url) == -1;
                if (newArr) {
                    const orginList = Array.isArray(newArr) ? newArr : [newArr];
                    const appendList = orginList.filter(el => el && notExist(el)).map(url => ({ url, name: getFileNameWithUrl(url), })) || [];
                    return this.uploadeFileList.push(...appendList);
                }
                this.uploadeFileList = []
            },
            immediate: true,
        }
    },
    computed: {
        showPercent(){
            if(this.uploadPercentList.length==0){
                return false;
            }

            if(this.uploadPercentList.every(el=>el.percent==0||el.percent==100)){
                return false;
            }
            
            return true;
        },
    },
    data() {
        return {
            uploadeFileList: [],
            uploadPercentList: [],
        }
    },
    methods: {
        // 生成百分比数组的元素
        generatePercentEle(){
            return {
                id: getRandomTimeStr(),
                percent: 0,
            }
        },
        onUploading(fileEle, { percent }) {
            fileEle.percent = Math.floor(percent * 100) / 100;
        },
        //参数必须是param，才能获取到内容
        uploadFile(param) {
            if (!this.folder) {
                const err = new Error('上传文件夹不得为空');
                param.onError(err);
                throw err;
            }
            // 获取上传的文件名
            var file = param.file
            const fileEle = this.generatePercentEle();
            this.uploadPercentList.push( fileEle );
            return uploadSingleFile({ file, folder: this.folder, onUploading: this.onUploading.bind(this, fileEle) }).then(path => {
                this.uploadeFileList.push({ uid: file.uid, url: path, name: getFileNameWithUrl(path) });
                this.fileChange();
                this.uploadPercentList.splice( this.uploadPercentList.indexOf(fileEle), 1 );
            });
        },
        fileChange() {
            this.$emit('fileChange', this.uploadeFileList);
        },
        handleExceed(files, fileList) {
            this.$message.warning(`文件数目超出限制`);
        },
        handleRemove(file) {
            const delIndex = this.uploadeFileList.findIndex(el => el.uid == file.uid);
            if (delIndex != -1) {
                this.uploadeFileList.splice(delIndex, 1);
                this.fileChange();
            }
        },
        // 文件顺序焦晃
        swapFile(index1,index2){
            const temp = deepCopy(this.uploadeFileList[index1]);
            mergeObject(this.uploadeFileList[index1], this.uploadeFileList[index2]);
            mergeObject(this.uploadeFileList[index2], temp);
            this.fileChange();
        },
        swapLeft(file){
            const index = this.uploadeFileList.indexOf(file);
            if(index>0){
                this.swapFile(index,index-1);
            }
        },
        swapRight(file){
            const index = this.uploadeFileList.indexOf(file);
            if(index<this.uploadeFileList.length-1){
                this.swapFile(index,index+1);
            }
        },
        filterFile(file) {
            const typeFlag = checkFileMimalType(file.type, this.accept);
            const sizeFlag = formatFileSize(file) <= this.maxSizeMB;
            if (!sizeFlag) {
                this.$message.warning(`文件大小不得超过 ${this.maxSizeMB} MB`);
            }
            return typeFlag && sizeFlag;
        },
    }
}
</script>

<style lang="scss" scoped>
.wrapper ::v-deep .el-upload--picture-card {
    display: none;
}

::v-deep .el-progress-bar {
    width: calc(90% - 8em) !important;
}

::v-deep .el-upload-list__item>div {
    height: 100%;
}

::v-deep .el-upload-list--picture-card .el-upload-list__item-thumbnail{
    object-fit: fill;
}

.tips {
    color: #939393;
    font-size: 12px;
}
</style>
